import 'reflect-metadata'
import { INJECTED_TOKEN } from './constants'

// 当前模块或提供者需要注入其他提供者
// token 是提供者的令牌
export function Inject(token: any) {
  // 参数装饰器装饰类的构造函数参数时接收3个参数
  // 类本身 参数名 参数索引( 从左往右 从0开始 ) 参数装饰器执行时 是从右往左依次执行
  return (target: Object, propertyKey: string, parameterIndex: number) => {
    // 从类上取 INJECTED_TOKEN 元数据 第一次为默认为空数组
    const existingInjectedTokens = Reflect.getMetadata(INJECTED_TOKEN, target) ?? []
    // 数组索引与构造函数参数服务对应 索引处保存令牌 token
    existingInjectedTokens[parameterIndex] = token
    // 给类添加一个 INJECTED_TOKEN 元数据 值是一个数组 里面的索引对应的值表示构造函数依赖的服务
    Reflect.defineMetadata(INJECTED_TOKEN, existingInjectedTokens, target)
  }
}